状态机
这里指客户端自定义状态机,即客户端单位上的状态机。一个单位可以有多个状态机,这些状态机同时tick, 但是最终只有优先级最高的一个状态机控制单位播动画。 除了服务端状态机同步过来的状态机,客户端还可以额外创建状态机。 客户端状态机有layer和priority属性,服务端状态机没有。 layer控制状态机影响全身(layer=0)、上半身(layer=1)、下半身(layer=2) priority控制状态机的优先级,移动状态机(priority=0)优先级最低,技能状态机(priority=1)比移动状态机优先级高,所以放技能的时候播技能动画,而不是移动动画, 尽管两个状态机都在tick。自定义装状态机的优先级一般设为2或2以上
状态机创建
状态机附属于单位,由单位创建状态机(也可以依赖服务端状态机同步来创建状态机)
get_or_create_state_machine
创建自定义服务端状态机,如果已经存在就返回存在的状态机
- 参数
- name (string) - 状态机名字,同一个单位上的状态机名字不能重复。注意不要使用形如"skill"的名字,这些被默认状态机占用了
- priority (uint) - 优先级
- layer (uint) - 影响层级,仅取值0(全身),1(上半身),2 (下半身)
- 返回
- sm (table) - 状态机lua对象
- new (bool) - 是否是新创建的
local sm, new = unit:get_or_create_state_machine('taunt', 2, 0)
状态机api
get_priority
获取状态机优先级
- 返回
- priority (uint)
local priority = sm:get_priority()
add_state
状态机添加状态,如果id已经有了就返回已经有的状态 注意:创建状态机的时候状态机默认创建id为-1, name为'exit'的状态,并且状态机的当前状态为'exit'
- 参数
- name (string) - 状态名(只是起描述性作用)
- id (int) - 状态id
- 返回
- state (table) - state的lua对象
local state = sm:add_state('idle', 0)
get_state
根据id获取状态机的状态
-
参数
- id (int) - 状态id
-
返回
- state (table) - state的lua对象
local exit_state = sm:get_state(-1)
set_current_state
根据id设置状态机的当前状态
- 参数
- id (int) - 状态id, 注意id对应的状态必须先添加到状态机,否则不生效
sm:set_current_state(id)
transit
状态机根据event id切换状态。如果是同步给客户端的状态机。服务端切状态了,客户端对应的状态机也会切状态。
- 参数
- id (uint8) - 事件id(
>
=0且<
=255), 注意id对应的事件必须先添加到状态转移表里,否则不生效
- id (uint8) - 事件id(
sm:transit(id)
set_animation_state
状态机设置播放的动画,如果状态机优先级高,在排序中胜出了,模型就会播放。
状态api
get_name
获取状态名
- 返回
- name (string)
local name = state:get_name()
get_id
获取状态id
- 返回
- id (int)
local state_id = state:get_id()
add_transition
状态添加转移表,即什么事件可以使状态机从当前状态切换到下一个状态
- 参数
- id (uint8) - 事件id,可以用enum来封装以明确含义,但是api接收的是uint8
- next(table)- 下一个状态的lua对象
local idle_state = sm:get_state(0)
local exit_state = sm:get_state(-1)
local event = {idle=0, exit=1}
exit_state:add_transition(event.idle, idle_state)
idle_state:add_transition(event.exit, exit_state)
回调
状态切换的时候会触发回调 回调调用顺序:比如从idle状态切换到walk状态,先调用idle:on_exit(), 再调用walk:on_enter(), 然后每帧调用walk:on_update(delta)
on_enter
进入状态的时候调用
- 参数
- self (table) - 状态的lua对象
local idle_state = sm:get_state(0)
function idle_state:on_enter()
log.info('enter idle state')
end
on_update
状态tick的时候调用
- 参数
- self (table) - 状态的lua对象
- delta (float) - 更新的delta时间,单位秒
local idle_state = sm:get_state(0)
function idle_state:on_update(delta)
log.info('update idle state, time elapsed', delta)
end